﻿using System;
using System.Collections.Generic;
using System.Text;
using Twitterizer.Framework;
using System.IO;
//using TwitterCon.Program;


namespace TwitterCon
{
    class Program
    {
        static void Main(string[] args)
        {
            string Reply = "";
            bool TimeToGo = false;

            Console.Title = "TwitterCon - Natural_Orang3 - 2008";

            try
            {
                MySettings settings = new MySettings();


                TwitterCommands Tc = new TwitterCommands(settings.UserName, settings.UserPass);

                try
                {

                    while (TimeToGo == false)
                    {
                        if (Reply.Length > 0)
                        {
                            if (Reply.StartsWith("!"))
                            {
                                if (Reply.StartsWith("!replies"))
                                {
                                    //Get Replies
                                    Tc.ShowReplies(settings.updates);
                                    Reply = Tc.Wait();
                                }
                                else if (Reply.StartsWith("!direct"))
                                {
                                    //Get Direct Message
                                    
                                    Reply = Tc.Wait();
                                }
                                else if (Reply.StartsWith("!public"))
                                {
                                    //Show Public TimeLine
                                    Tc.ShowPublicTimeLine(settings.updates);
                                    Reply = Tc.Wait();
                                }
                                else if (Reply.StartsWith("!friends"))
                                {
                                    Tc.ShowFriends();
                                    Reply = Tc.Wait();

                                }
                                else if (Reply.StartsWith("!followers"))
                                {
                                    Tc.ShowFollowers();
                                    Reply = Tc.Wait();

                                }
                                else
                                {
                                    //Unknow Command
                                    Reply = Tc.Wait();
                                }
                            }
                            else
                            {
                                //If It doesn't start with a ! then its an update to send... 
                                //Not Sure if this is still the best way to handle it
                                //update twittert
                                Tc.SendUpdate(Reply);
                                Reply = "";
                            }
                        }
                        else
                        {
                            Tc.ShowUpdates(settings.updates);
                            Reply = Tc.Wait();
                        }
                    }

                }
                catch (Exception ex)
                {
                    Console.Clear();
                    Console.WriteLine("Error: ");
                    Console.WriteLine("--> Message: " + ex.Message);
                    Console.WriteLine("--> Stack Trace: " + ex.StackTrace);
                    Console.WriteLine("");
                    Console.WriteLine("Check to make sure settings.ini is setup properly.");
                    Console.WriteLine("");
                    Console.WriteLine("Check to make sure twitter.com is alive.");

                }





            }
            catch (Exception ex0)
            {
                Console.Clear();
                Console.WriteLine("Error Parsing Settings.ini!!");
                Console.WriteLine("");
                Console.WriteLine(ex0.Message);

            }
            Console.ReadKey();
        }


        class TwitterCommands
        {
            public TwitterCommands(string username, string password)
            {
                T = new Twitter(username, password);
                myusername = username;
            }

            private Twitter T;
            private string myusername;

            public string Wait()
            {
                Console.WriteLine("");
                Console.Write("  ►");

                if (Console.CursorTop <= 73)
                {

                    Console.WindowHeight = Console.CursorTop + 2;
                }
                else
                {
                    Console.WindowHeight = 73;
                }

                int cleft = Console.CursorLeft;
                int ctop = Console.CursorTop;

                Console.SetCursorPosition(0, 0);
                Console.SetCursorPosition(cleft, ctop);

                return Console.ReadLine();
            }

            public void SendUpdate(string Status)
            {
                Console.Clear();
                Console.WriteLine("Sending Status Update... Please Wait.");
                
                T.Update(Status);
            }

            private void WriteUpdate(TwitterStatus s)
            {
                string favorite = "";
                if (s.IsFavorited) favorite = " ♥";

                
                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));

                Console.WriteLine(StringHelp.stretch(" │" + s.TwitterUser.ScreenName + favorite, " ", StringHelp.GetDateTimeString(s.Created) + " │"));

                Console.WriteLine(StringHelp.stretch(" ├", "─", "┤"));

                string update = s.Text;

                update = StringHelp.RemoveAndNewlineLineFeed(update);
                update = update.Trim();

                if (update.Length > Console.WindowWidth - 4)
                {

                    foreach (string u in StringHelp.SplitToLines(update))
                    {
                        Console.WriteLine(StringHelp.flank(u));

                    }

                }
                else
                {

                    Console.WriteLine(StringHelp.flank(s.Text));
                }

                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));
                Console.WriteLine("");

            }

            private void WriteStatusCollection(TwitterStatusCollection collection, int num)
            {
                int count = -1;

                foreach (TwitterStatus s in collection)
                {

                    count++;

                    if (count < num)
                    {
                        WriteUpdate(s);
                    }

                }
            }

            private void WriteUserCollection(TwitterUserCollection collection)
            {


                Console.WriteLine(StringHelp.stretch(" ├", "─", "┤"));

               
                string user0 = "";
                string user1 = "";
                string user2 = "";

                if (collection.Count > 0)
                {

                    for (int x = 0; x <= collection.Count - 1; x = x + 3)
                    {

                        try { user0 = collection[x].UserName; }
                        catch { user0 = ""; }

                        try { user1 = collection[x+1].UserName; }
                        catch { user1 = ""; }

                        try { user2 = collection[x+2].UserName; }
                        catch { user2 = ""; }

                        Console.WriteLine(StringHelp.threecolumns(user0, user1, user2));
                    }
                }
                else
                {
                    Console.WriteLine(StringHelp.flank(" You Have no friends :("));
                }
                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));
                //Console.WriteLine("");


            }

            /// <summary>
            /// Download and Display Updates to the UserTimeline
            /// </summary>
            /// <param name="number">Number of Updates to Display</param>
            public void ShowUpdates(int number)
            {

                //## GETTING UPDATES ##

                Console.Clear();

                Console.WriteLine("Downloading Updates... Please Wait.");

                TwitterStatusCollection stats = T.FriendsTimeline();

                Console.Clear();

                //## DISPLAYING UPDATES

                string StatusLine = "Status Updates for: " + myusername + " - Updated: " + DateTime.Now.ToShortTimeString();

                Console.WriteLine("");

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));

                Console.WriteLine(StringHelp.flank(StatusLine));

                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));
                
                Console.WriteLine("");

                WriteStatusCollection(stats, number);

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));
                Console.WriteLine(StringHelp.flank("[Enter] to Refresh, Type a status and [Enter] to send status to Twitter."));
                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));

            }

            /// <summary>
            /// Download and Display @Replies
            /// </summary>
            /// <param name="number">Number of Replies to Display</param>
            public void ShowReplies(int number)
            {
                //## GETTING UPDATES ##

                Console.Clear();

                Console.WriteLine("Downloading Replies... Please Wait.");

                TwitterStatusCollection stats = T.Replies();

                Console.Clear();

                //## DISPLAYING UPDATES

                //string StatusLine = "Replies to: " + username + " - Updated: " + DateTime.Now.ToShortTimeString();

                Console.WriteLine("");

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));

                Console.WriteLine(StringHelp.stretch(" │ Replies to: " + myusername, " ", DateTime.Now.ToShortTimeString() + " │"));

                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));

                Console.WriteLine("");

                WriteStatusCollection(stats, number);

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));
                Console.WriteLine(StringHelp.flank("[Enter] to Refresh, Type a status and [Enter] to send status to Twitter."));
                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));

            }

            /// <summary>
            /// Download and Display Updates from the Twitter Public Timeline
            /// </summary>
            /// <param name="number"></param>
            public void ShowPublicTimeLine(int number)
            {

                //## GETTING UPDATES ##

                Console.Clear();

                Console.WriteLine("Downloading Public Timeline... Please Wait.");

                TwitterStatusCollection stats = T.PublicTimeline();

                Console.Clear();

                //## DISPLAYING UPDATES

                //string StatusLine = "Twitter Public Timeline - Updated: " + DateTime.Now.ToShortTimeString();

                Console.WriteLine("");

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));

                Console.WriteLine(StringHelp.stretch(" │ Twitter Public Timeline", " ", DateTime.Now.ToShortTimeString() + " │"));

                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));

                Console.WriteLine("");

                WriteStatusCollection(stats, number);

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));
                Console.WriteLine(StringHelp.flank("[Enter] to Refresh, Type an update and [Enter] to send status to Twitter."));
                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));

            }

            /// <summary>
            /// Download and Display Friends (who the user is following)
            /// </summary>
            public void ShowFriends()
            {
                //Getting Updates

                Console.Clear();

                Console.WriteLine("Getting Friends... Please Wait.");

                TwitterUserCollection twits = T.Friends();

                Console.Clear();

                //Displaying

                Console.WriteLine("");

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));

                Console.WriteLine(StringHelp.stretch(" │ Friends of: " + myusername + "(" + twits.Count.ToString() + ")", " ", StringHelp.GetDateTimeString(DateTime.Now) + " │"));

               // Console.WriteLine(sh.stretch(" └", "─", "┘"));

              //  Console.WriteLine("");

                WriteUserCollection(twits);

            }

            /// <summary>
            /// 
            /// </summary>
            public void ShowFollowers()
            {
                //Getting Updates
                                


                Console.Clear();

                Console.WriteLine("Getting Followers... Please Wait.");

                TwitterUserCollection twits = T.Followers();

                Console.Clear();

                //Displaying

                Console.WriteLine("");

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));

                Console.WriteLine(StringHelp.stretch(" │ Followers of: " + myusername + "(" + twits.Count.ToString() + ")", " ", StringHelp.GetDateTimeString(DateTime.Now) + " │"));

                // Console.WriteLine(sh.stretch(" └", "─", "┘"));

                //  Console.WriteLine("");

                WriteUserCollection(twits);

            }

            public void ShowUsage()
            {
                Console.WriteLine("");

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));

                Console.WriteLine(StringHelp.stretch(" │ Help for TwitterCon", " ", " John Rutherford - 2008 │"));

                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));
                
                Console.WriteLine("");

                Console.WriteLine(StringHelp.stretch(" ┌", "─", "┐"));
                
                Console.WriteLine(StringHelp.flank("!replies"));
                Console.WriteLine(StringHelp.flank("!replies"));
                Console.WriteLine(StringHelp.flank("!replies"));
                Console.WriteLine(StringHelp.flank("!replies"));
                Console.WriteLine(StringHelp.stretch(" └", "─", "┘"));
            }
        }

        class MySettings
        {
            public MySettings()
            {
                List<string> mylines = ReadFromFile("settings.ini");

                foreach (string s in mylines)
                {
                    if (s.Contains("=") && !(s.StartsWith("//")))
                    {
                        if (s.Split('=')[0] == "password") { UserPass = s.Split('=')[1]; }
                        if (s.Split('=')[0] == "username") { UserName = s.Split('=')[1]; }
                        if (s.Split('=')[0] == "updates") { updates = int.Parse(s.Split('=')[1]); }
                    }
                }

            }

            static List<string> ReadFromFile(string filename)
            {
                List<string> lines = new List<string> { };

                StreamReader SR;
                string S;
                SR = File.OpenText(filename);
                S = SR.ReadLine();
                while (S != null)
                {
                    lines.Add(S);
                    S = SR.ReadLine();
                }
                SR.Close();

                SR = null;

                return lines;
            }

            public string UserName = "";
            public string UserPass = "";
            public int updates = 5;
        }

        /// <summary>
        /// Provides Help when writing to a console. Stretching text, providing date stamps, etc.
        /// </summary>
        static class StringHelp
        {
            /// <summary>
            /// Return a TimeStamp Relative to the current day (Today 10:15, Yesterday 12:00)
            /// </summary>
            /// <param name="date"></param>
            /// <returns></returns>
            public static string GetDateTimeString(DateTime date)
            {
                string datestr = "";

                if (date.ToLocalTime().Date == DateTime.Now.Date)
                {
                    datestr = "Today";
                }
                else if (date.ToLocalTime().DayOfYear == DateTime.Now.DayOfYear - 1)
                {
                    datestr = "Yesterday";

                }
                else
                {
                    datestr = date.ToLocalTime().ToShortDateString();
                }
                                             
                string timestr = "";

                timestr = date.ToLocalTime().ToShortTimeString();


                return datestr + " " + timestr;

            }

            public static string RemoveAndNewlineLineFeed(string s)
            {
                char[] lf = { '\r', '\n' };
                return string.Join("", s.Split(lf));
            }

            public static List<string> SplitToLines(string s)
            {
                List<string> TextList = new List<string> { };

                TextList.Add(GetSubStrSpc(s).Trim());
                s = s.Remove(0, GetSubStrSpc(s).Length);

                while (s.Length > 0)
                {
                    if (s.Length >= Console.WindowWidth - 4)
                    {
                        //Console.WriteLine("--> Getting substring");
                        TextList.Add(GetSubStrSpc(s).Trim());

                        s = s.Remove(0, GetSubStrSpc(s).Length);
                    }
                    else
                    {
                        //Console.WriteLine("--> Not Getting Substring");
                        TextList.Add(s.Trim());
                        s = "";
                    }
                }


                return TextList;
            }

            /// <summary>
            /// Repeat M to fill the width of the console between L and R
            /// </summary>
            /// <param name="L"></param>
            /// <param name="M"></param>
            /// <param name="R"></param>
            /// <returns></returns>
            public static string stretch(string L, string M, string R)
            {
                return L + repeat(M, Console.WindowWidth - (L.Length + R.Length)) + R;
            }

            private static string repeat(string Text, int Times)
            {
                string Return = "";
                int done = 1;


                while (done < Times)
                {
                    done++;

                    Return += Text;
                }

                return Return;
                 
            }

            /// <summary>
            /// Put a pipe on either side of some text and strecht to console width
            /// </summary>
            /// <param name="Text"></param>
            /// <returns></returns>
            public static string flank(string Text)
            {
                while (Text.Length < Console.WindowWidth - 4)
                {
                    Text += " ";
                }

                Text = " │" + Text + "│";

                return Text;
            }

            public static string threecolumns(string col0, string col1, string col2)
            {
                string returntext = "";
                    
                returntext += " │ [ ";

                returntext += col0 + repeat(" ", 20 - col0.Length);

                returntext += "] [ ";

                returntext += col1 + repeat(" ", 20 - col1.Length);

                returntext += "] [ ";

                returntext += col2 + repeat(" ", 20 - col2.Length);

                returntext += "]" + repeat(" ", Console.WindowWidth - (returntext.Length + 2)) + "│";

                return returntext;
            }

            private static string GetSubStrSpc(string text)
            {
                //Find Max Length of the string to return
                //Console Width - A space on each side and the | on each side

                int maxLen = Console.WindowWidth - 4;

                //Console.WriteLine("In GetSubStrSpc()");

                //Get the biggest string
                string maxString = text.Substring(0, maxLen);

                if (text.Contains(" "))
                {
                    // If The text has a space split it at that...

                    int lastSpc = maxString.LastIndexOf(' ');

                    //if (lastSpc > maxLen - 10)
                    //{

                    //    return maxString;

                    //}
                    //else
                    //{
                    string minString = text.Substring(0, lastSpc);

                    return minString;
                    //}

                }
                else
                {
                    //If it doesn't have a space just grab the largest string that will fit

                    return maxString;
                }


            }

        }

    }


}
